package com.codejoys.ssm.service.Impl;

import com.codejoys.ssm.dao.ThesisDao;
import com.codejoys.ssm.domain.StudentThesis;
import com.codejoys.ssm.domain.StudentThesisExample;
import com.codejoys.ssm.domain.Thesis;
import com.codejoys.ssm.exception.TmsException;
import com.codejoys.ssm.mapper.StudentThesisMapper;
import com.codejoys.ssm.mapper.ThesisMapper;
import com.codejoys.ssm.service.ThesisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
//对象只有一个，单例模式，一个对象只能由一个进程访问，但是可以有多个进程尽进来
public class ThesisServiceImpl  implements ThesisService {

    private static Logger logger= LoggerFactory.getLogger(ThesisServiceImpl.class);
    @Autowired
    ThesisMapper thesisMapper;
    @Autowired
    StudentThesisMapper studentThesisMapper;
    @Autowired
    ThesisDao thesisDao;


    @Override
    public void insert(Thesis thesis) {
        //thesisMapper.insert(thesis);
        thesisMapper.insertSelective(thesis);
    }

    @Override
    public void update(Thesis thesis) {
        //thesisMapper.updateByPrimaryKey();
        //selectService 对象里面的属性不为空才更新
        thesisMapper.updateByPrimaryKeySelective(thesis);
    }

    //经过事务处理
    @Transactional
    @Override
    public void delete(Integer tid) {
        //物理删除
        //thesisMapper.deleteByPrimaryKey(tid);

        //使用排他锁，删除课题时，不能同时做选课操作
        //select * from thesis where id=tid(4) for update

        thesisDao.lockThesis(tid);//排他锁
        //如果课题已经被选，不能删除
        //判断当前课题有没有被选
        //select count(*) from student_thesis where tid=7

        StudentThesisExample example=new StudentThesisExample();
        example.createCriteria().andTidEqualTo(tid);

        final long count = studentThesisMapper.countByExample(example);
        if (count>0){//课程已被选
           // System.out.println("课程已有学生选择了，不能删除！");
            logger.warn("课程已经有学生选择了，不能删除");

            throw new TmsException(3001,"课程已经有学生选择了，不能删除");
            //throw new RuntimeException("普通运行时异常");

        }

        Thesis thesis=new Thesis();
        thesis.setId(tid);
        thesis.setStatus("1");//"0"表示正常 “1”表示删除
        thesisMapper.updateByPrimaryKeySelective(thesis);
    }

    //学生选课
    @Transactional
    @Override
    public void chooseThesis(Long studentId, Integer thesisId) {

    //select * from thesis where id=tid(4) for update
        //加锁，防止老师删除课题
        //防止多个学生选同样的课程
        thesisDao.lockThesis(thesisId);


        //todo:防止一个学生报名多门课程，只能一个一个报名
        //todo:防止其他老师选定当前学生
        //对学生ID加锁
        thesisDao.lockStudent(studentId);

        //删除的课题不能再选
        final Thesis thesis = thesisMapper.selectByPrimaryKey(thesisId);
        if (thesis!=null && "1".equals(thesis.getStatus())){
            throw  new TmsException(3004,"课程已经被老师删除，请选择其他课题！");
        }
        //已选课题不能再选
        if (thesis!=null && "3".equals(thesis.getStatus())){
            throw new TmsException(3005,"课题已经被选定给其它学生，不能再选！请选择其他课题。");
        }

        //课题最多三个人选
        StudentThesisExample e=new StudentThesisExample();
        e.createCriteria().andTidEqualTo(thesisId);

        final long count = studentThesisMapper.countByExample(e);
        if (count>3){
            throw new TmsException(3006,"课题已经被选满，不能再选！请选择其他课题。");
        }

        //一人最多选三门课
        StudentThesisExample e2=new StudentThesisExample();
        e2.createCriteria().andTidEqualTo(thesisId);
        final long count2 = studentThesisMapper.countByExample(e2);
        if (count2>3){
            throw new TmsException(3007,"你选择的课题超过了数量限制，不能再选！");
        }

        //查询当前学生是否有选定的课题
        Thesis thesis1 = thesisDao.findSelectedThesis(studentId);
        if (thesis1!=null){
            throw new TmsException(3008,"你已经被其它老师选定了，不能再选！");
        }

        //往中间表插入选课记录
        StudentThesis st=new StudentThesis();
        st.setUid(studentId);
        st.setTid(thesisId);
        studentThesisMapper.insertSelective(st);
    }


    //选定学生（老师）
    @Transactional
    @Override
    public void chooseStudent(Integer thesisId, Long studentId) {

        //防止学生被其它老师选定
        thesisDao.lockStudent(studentId);

        //防止学生删除选课
        thesisDao.lockThesis(thesisId);


     final Thesis count = thesisDao.findSelectedThesis(studentId);

        if (count!=null){
            throw new TmsException(3010,"学生已经有选定的课题，不能再选！");
        }

        final StudentThesis studentThesis = studentThesisMapper.selectByPrimaryKey(studentId, thesisId);
        if (studentThesis==null){
            throw new TmsException(3011,"学生已经删除了您的选课，不能再选！");
        }

        //删除学生其他选课
        StudentThesisExample e=new StudentThesisExample();
        e.createCriteria().andUidEqualTo(studentId)
                          .andTidNotEqualTo(thesisId);
        studentThesisMapper.deleteByExample(e);

        //删除课程其他学生
        StudentThesisExample e2=new StudentThesisExample();
        e.createCriteria().andUidEqualTo(studentId)
                .andTidNotEqualTo(thesisId);
        studentThesisMapper.selectByExample(e);

        //修改课程状态为已选定
        Thesis thesis=new Thesis();
        thesis.setId(thesisId);
        thesis.setStatus("3");
    }
}
